#ifndef __PANEL_CHORUS_H__
#define __PANEL_CHORUS_H__

#include <wx/wx.h>
#include <wx/aui/aui.h>
#include <wx/wrapsizer.h>
#include <wx/event.h>
#include <wx/xml/xml.h>
#include "MyCommon.h"

class MyEventChorus : public wxCommandEvent {
public:
    MyEventChorus(wxEventType eventType = wxEVT_NULL,int id = 0)
        : wxCommandEvent(eventType, id) {

        }

    // 克隆事件对象
//    [[nodiscard]] // C++17 才支持，意思就是函数返回值不能被忽略，否则编译器发出警告
    virtual wxEvent *Clone() const override {
        return new MyEventChorus(*this);
    }

    void SetDry(double dry) {
        m_dry = dry;
    }
    void SetWet(double wet) {
        m_wet = wet;
    }
    void SetRate(double rate) {
        m_rate = rate;
    }
    void SetTone(double tone) {
        m_tone = tone;
    }
    void SetPitch(double pitch) {
        m_pitch = pitch;
    }
    void SetEnable(bool enable) {
        this->enable = enable;
    }
    double GetDry() {
        return m_dry;
    }
    double GetWet() {
        return m_wet;
    }
    double GetRate() {
        return m_rate;
    }
    double GetPitch() {
        return m_pitch;
    }
    double GetTone() {
        return m_tone;
    }
    bool GetEnable() {
        return enable;
    }
    void SetPresetIndex(const unsigned int index) {
        preset_index = index;
    }
    int GetPresetIndex() {
        return preset_index;
    }


private:

    double m_dry;
    double m_wet;
    double m_rate;
    double m_pitch;
    double m_tone;
    bool enable;
    int preset_index;
};

wxDECLARE_EVENT(myEVT_CHORUS, MyEventChorus);
wxDECLARE_EVENT(myEVT_CHORUS_DRY, MyEventChorus);
wxDECLARE_EVENT(myEVT_CHORUS_WET, MyEventChorus);
wxDECLARE_EVENT(myEVT_CHORUS_RATE, MyEventChorus);
wxDECLARE_EVENT(myEVT_CHORUS_PITCH, MyEventChorus);
wxDECLARE_EVENT(myEVT_CHORUS_TONE, MyEventChorus);
wxDECLARE_EVENT(myEVT_CHORUS_ENABLE, MyEventChorus);

typedef void (wxEvtHandler::*MyChorusEventFunction)(MyEventChorus &);

#define MyChorusEventHandler(func) \
    wxEVENT_HANDLER_CAST(MyChorusEventFunction, func)

#define M_EVT_CHORUS(id, fn) \
    wx__DECLARE_EVT1(myEVT_CHORUS, id, MyChorusEventHandler(fn))
#define M_EVT_CHORUS_DRY(id, fn) \
    wx__DECLARE_EVT1(myEVT_CHORUS_DRY, id, MyChorusEventHandler(fn))
#define M_EVT_CHORUS_WET(id, fn) \
    wx__DECLARE_EVT1(myEVT_CHORUS_WET, id, MyChorusEventHandler(fn))
#define M_EVT_CHORUS_RATE(id, fn) \
    wx__DECLARE_EVT1(myEVT_CHORUS_RATE, id, MyChorusEventHandler(fn))
#define M_EVT_CHORUS_PITCH(id, fn) \
    wx__DECLARE_EVT1(myEVT_CHORUS_PITCH, id, MyChorusEventHandler(fn))
#define M_EVT_CHORUS_TONE(id, fn) \
    wx__DECLARE_EVT1(myEVT_CHORUS_TONE, id, MyChorusEventHandler(fn))
#define M_EVT_CHORUS_ENABLE(id, fn) \
    wx__DECLARE_EVT1(myEVT_CHORUS_ENABLE, id, MyChorusEventHandler(fn))


class PanelChorus : public wxPanel
{
public:
    PanelChorus(const wxString &title, wxXmlNode *node, wxWindowID id = wxID_ANY, wxWindow *parent = nullptr);
    typedef struct
    {
        bool enable;
        float dry;
        float wet;
        float pitch;
        float rate;
        float tone;
    }param_struct;


private:

    // enum{
    //     ID_TXT_DRY = ID_START_PANEL_CHORUS + 1,
    //     ID_TXT_WET,
    //     ID_TXT_PITCH,
    //     ID_TXT_RATE,
    //     ID_TXT_TONE,
    //     ID_SLI_DRY,
    //     ID_SLI_WET,
    //     ID_SLI_PITCH,
    //     ID_SLI_RATE,
    //     ID_SLI_TONE,
    //     ID_CHK_SWITCH,
    // };

    enum{
        EV_DRY=1,
        EV_WET,
        EV_PITCH,
        EV_RATE,
        EV_TONE,
        EV_ENABLE,
    };

    const double dry_max = 6;
    const double dry_min = -30;
    const double dry_step = 0.1;
    const double wet_max = 6;
    const double wet_min = -30;
    const double wet_step = 0.1;
    const double pitch_max = 1;
    const double pitch_min = 0;
    const double pitch_step = 0.01;
    const double rate_max = 1;
    const double rate_min = 0;
    const double rate_step = 0.01;
    const double tone_max = 1;
    const double tone_min = 0;
    const double tone_step = 0.01;

    const char *attr_name_select = "select";
    const char *attr_name_preset_default = "default";
    const char *attr_name_param_tone = "tone";
    const char *attr_name_param_pitch = "pitch";
    const char *attr_name_param_rate = "rate";
    const char *attr_name_param_wet = "wet";
    const char *attr_name_param_dry = "dry";
    const char *attr_name_param_enable = "enable";

    wxWindowID ID_TXT_DRY;
    wxWindowID ID_TXT_WET;
    wxWindowID ID_TXT_PITCH;
    wxWindowID ID_TXT_RATE;
    wxWindowID ID_TXT_TONE;
    wxWindowID ID_SLI_DRY;
    wxWindowID ID_SLI_WET;
    wxWindowID ID_SLI_PITCH;
    wxWindowID ID_SLI_RATE;
    wxWindowID ID_SLI_TONE;
    wxWindowID ID_CHK_SWITCH;
    wxWindowID ID_CHO_PRESET;

    wxAuiPaneInfo paneInfo;
    MyEventChorus param_event;
    param_struct param;
    wxXmlNode *root_node;
    wxXmlNode *preset_node;
    wxWindowID this_id;
    int select_index;

public:

    wxAuiPaneInfo &GetPaneInfo();
    void SetShow(bool show);
    double SetParamDry(double value);
    double SetParamWet(double value);
    double SetParamPitch(double value);
    double SetParamRate(double value);
    double SetParamTone(double value);
    bool SetParamEnable(bool value);
    double GetParamDry();
    double GetParamWet();
    double GetParamPitch();
    double GetParamRate();
    double GetParamTone();
    bool GetParamEnable();
    void SetPresetIndex(const unsigned int index);
    int GetPresetIndex();
    void PresetListClear(void);
    void AddPresetList(const wxString &preset_name);
    wxXmlNode *SaveCurrentParamsToNewPreset(wxXmlNode *root, const wxString &new_preset_name,int &is_same);
    bool WriteToXML(wxXmlNode *node);

private:
    void OnSliderChange(wxCommandEvent& event);
    void OnTextEnter(wxCommandEvent& event);
    void OnChkChange(wxCommandEvent& event);
    void OnCombChange(wxCommandEvent& event);

    void TrigerEvent(int ev);
    wxXmlNode *SelectPreset(wxString name);

    // wxDECLARE_EVENT_TABLE();
};


#endif
